#include <iostream>
#include <fstream>
#include "pb_cfg_magicdoor.pb.h"
#include "CMagicDoorMgr.h"
#include "../mainctrl.h"
#include "../simpleconfig/CMonsterConfig.h"
#include "../data/CPlayerCacheData.h"
#include "../data/CPlayerOnlineData.h"
#include "../status/CUserStatus.h"
#include "../boss/CWorldBossCfg.h"
#include "../battle/CBattleRole.h"
#include "../battle/CBattleMgr.h"
#include "../clan/CClanEntry.h"
#include "../clan/CClanMgr.h"
#include "../map/CMapView.h"
#include "MsgBattle.pb.h"
#include "MsgAct.pb.h"
#include "MsgGM.pb.h"

template<>
bool CTRankArray<CMagicDoorContriUnit, MAX_CONTRIBUTE_LIST>::IsSame(
        CMagicDoorContriUnit& stA, CMagicDoorContriUnit& stB) const
{
    return (stA.GetGID() == stB.GetGID());
}

template<>
int CTRankArray<CMagicDoorContriUnit, MAX_CONTRIBUTE_LIST>::CmpFunc(
        CMagicDoorContriUnit& stA, CMagicDoorContriUnit& stB) const
{
    if (stA.GetCount() > stB.GetCount())
    {
        return 1;
    }
    else if (stA.GetCount() < stB.GetCount())
    {
        return -1;
    }

    return 0;
}

int CMagicDoorMgr::LoadConfig(const char* szCfgPath)
{
    int iRet = 0;

    if (szCfgPath == NULL)
    {
        CT_ERROR(("magic door Cfg Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_magicdoor stMagicDoorCfg;
    std::fstream stFileInput(szCfgPath, std::ios::in | std::ios::binary);
    if (!stMagicDoorCfg.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse magic door config!"));
        return RET_SYSTEM_FAIL;
    }

    SetCheckJoinDay(true);

    //解析魔界门等级配置文件内容
    CT_TRACE(("magic door level config count %d",
              stMagicDoorCfg.magic_level_config_rows_size()));

    CTLib::CTArray<int, MAX_CONTRIBUTE_LIST> aiContriGift;
    CTLib::CTArray<CLevelGiftUnit, MAGIC_DOOR_LEVEL_ACT_GIFT_COUNT> astActGift;

    CLevelGiftUnit stGiftUnit;
    CMagicDoorLevelCfgData stLevelCfgData;
    for (int i = 0; i < stMagicDoorCfg.magic_level_config_rows_size(); ++i)
    {
        const pb_cfg_magicdoor_pb_cfg_magic_level_config_unit& stLevelPBUnit =
            stMagicDoorCfg.magic_level_config_rows(i);

        aiContriGift.Clear();
        astActGift.Clear();
        stLevelCfgData.Clear();

        stLevelCfgData.SetLevel(stLevelPBUnit.level());
        stLevelCfgData.SetNeedExp(stLevelPBUnit.need_exper());
        stLevelCfgData.SetContributeAward(stLevelPBUnit.contribute_award());
        stLevelCfgData.SetSpecialBoss(stLevelPBUnit.special_boss());
        stLevelCfgData.SetBossNum(stLevelPBUnit.boss_nums());

        aiContriGift.AddOneItem(stLevelPBUnit.contribute_gift_1());
        aiContriGift.AddOneItem(stLevelPBUnit.contribute_gift_2());
        aiContriGift.AddOneItem(stLevelPBUnit.contribute_gift_3());

        stGiftUnit.SetGiftID(stLevelPBUnit.gift_id_1());
        stGiftUnit.SetGiftNum(stLevelPBUnit.gift_num_1());
        astActGift.AddOneItem(stGiftUnit);
        stGiftUnit.SetGiftID(stLevelPBUnit.gift_id_2());
        stGiftUnit.SetGiftNum(stLevelPBUnit.gift_num_2());
        astActGift.AddOneItem(stGiftUnit);
        stGiftUnit.SetGiftID(stLevelPBUnit.gift_id_3());
        stGiftUnit.SetGiftNum(stLevelPBUnit.gift_num_3());
        astActGift.AddOneItem(stGiftUnit);
        stGiftUnit.SetGiftID(stLevelPBUnit.gift_id_4());
        stGiftUnit.SetGiftNum(stLevelPBUnit.gift_num_4());
        astActGift.AddOneItem(stGiftUnit);
        stGiftUnit.SetGiftID(stLevelPBUnit.gift_id_5());
        stGiftUnit.SetGiftNum(stLevelPBUnit.gift_num_5());
        astActGift.AddOneItem(stGiftUnit);

        for (int i = 0; i < aiContriGift.Size(); ++i)
        {
            if (aiContriGift[i] > 0)
            {
                if (!CMainCtrl::m_pstMain->m_stItemMgr.IsGiftValid(
                        (unsigned int)aiContriGift[i]))
                {
                    CT_RETURN(ERROR_GIFT_CONFIG_NONE);
                }
                stLevelCfgData.AddContriGift(aiContriGift[i]);
            }
        }

        for (int i = 0; i < astActGift.Size(); ++i)
        {
            if (astActGift[i].GetGiftID() > 0)
            {
                if (!CMainCtrl::m_pstMain->m_stItemMgr.IsGiftValid(
                        (unsigned int)astActGift[i].GetGiftID()))
                {
                    CT_RETURN(ERROR_GIFT_CONFIG_NONE);
                }
                stLevelCfgData.AddActGift(astActGift[i]);
            }
        }
        
        if (!stLevelCfgData.IsValidData())
        {
            return ERROR_MAGIC_DOOR_LEVEL;
        }

        iRet = _stMagicDoorCfg.AddLevelConfig(stLevelCfgData);
        CT_RETURN(iRet);
    }

    //解析充能消耗贡献度配置文件内容
    CT_TRACE(("magic door consume contribute config count %d",
              stMagicDoorCfg.consume_contribute_rows_size()));

    CMagicDoorConsumeCfgData stConsumeCfgData;

    for (int i = 0; i < stMagicDoorCfg.consume_contribute_rows_size(); ++i)
    {
        const pb_cfg_magicdoor_pb_cfg_consume_contribute_unit& stConsumePBUnit =
            stMagicDoorCfg.consume_contribute_rows(i);

        stConsumeCfgData.Clear();

        stConsumeCfgData.SetTimes(stConsumePBUnit.pay_times());
        stConsumeCfgData.SetSubContribute(stConsumePBUnit.sub_contribute());

        iRet = _stMagicDoorCfg.AddConsumeConfig(stConsumeCfgData);
        CT_RETURN(iRet);
    }

    return 0;
}

//获取魔界门信息
int CMagicDoorMgr::GetMagicDoorInfo(CPlayerDetailInfo& stPlayerDetail,
        MsgAnsMagicDoor& stAns)
{
    int iIndex = 0;
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_TRACE(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chNowLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    MsgMagicDoorInfo* pstDoorInfo = stAns.mutable_door_info();
    if (pstDoorInfo)
    {
        pstDoorInfo->set_day_total_pay(
            GetPayContriTimes(stPlayerDetail, true));
        pstDoorInfo->set_day_pay_limit(MAGIC_DOOR_MAX_PAY_TIMES);
        pstDoorInfo->set_door_status(stClanEntry._stMagicDoor._chStatus);
        pstDoorInfo->set_door_level(stClanEntry._stMagicDoor._chNowLevel);
        pstDoorInfo->set_door_exper(stClanEntry._stMagicDoor._iExp);
        pstDoorInfo->set_door_closed_time(0);
        if(stClanEntry._stMagicDoor._chStatus > 0)
        {
            pstDoorInfo->set_door_closed_time(
                stClanEntry._stMagicDoor._iOpenTime +
                    MAGIC_DOOR_TIME_AFTER_OPEN);
        }
        pstDoorInfo->set_door_exper_cur_max(stLevelCfgData.GetNeedExp()); 
    }
    else
    {
        CT_ERROR(("MsgMagicDoorInfo pb pointer null!"));
    }

    return 0;
}

int CMagicDoorMgr::CheckMagicDoorDataZero(CClanEntry& stClanEntry)
{
    if (1 == stClanEntry._stMagicDoor._chStatus &&
        CMainCtrl::m_pstMain->m_iNow >= stClanEntry._stMagicDoor._iOpenTime +
            MAGIC_DOOR_TIME_AFTER_OPEN)
    {
        stClanEntry._stMagicDoor._chOpenLevel = 0;
        stClanEntry._stMagicDoor._chStatus = 0;
        stClanEntry._stMagicDoor._iWorldLevel = 0;
        stClanEntry._stMagicDoor._astMonsterList.Clear();
    }

    return 0;
}

void CMagicDoorMgr::CheckPayContriTimes(CPlayerDetailInfo& stPlayerDetail,
        CClanEntry& stClanEntry)
{
    if (stClanEntry._stMagicDoor._iOpenTime <= 0 ||
            (stPlayerDetail._stUserClan._stMagicDoor._iLastPayTime >
                stClanEntry._stMagicDoor._iOpenTime))
    {
        return;
    }

    short shTimes = 0;
    short shTimesTmp = 0;
    shTimes = stPlayerDetail._stUserClan._stMagicDoor._stPayContriTimes.Get(
        CMainCtrl::m_pstMain->m_iNow);
    shTimesTmp = (short)(shTimes & 0xFF);
    shTimesTmp = (shTimesTmp << 8);
    shTimesTmp = (short)(shTimesTmp | shTimes);

    stPlayerDetail._stUserClan._stMagicDoor._stPayContriTimes.Set(
        shTimesTmp, CMainCtrl::m_pstMain->m_iNow);
}

int CMagicDoorMgr::GetPayContriTimes(CPlayerDetailInfo& stPlayerDetail,
        bool bTotal)
{
    //stPlayerDetail._stUserClan._stMagicDoor._stPayContriTimes存储16位的short
    //低8位存储23点循环中总的充能次数
    //高8位存储本次循环开启传送门之前的充能次数
    int iTotalTimes = 0;
    int iTimesBeforeOpen = 0;
    short shTimes = 0;
    shTimes = stPlayerDetail._stUserClan._stMagicDoor._stPayContriTimes.Get(
        CMainCtrl::m_pstMain->m_iNow);

    iTotalTimes = (int)(shTimes & 0xFF);

    if (bTotal)
    {
        return iTotalTimes;
    }

    iTimesBeforeOpen = (int)(shTimes & 0xFFFF);
    iTimesBeforeOpen = (int)(iTimesBeforeOpen >> 8);

    return iTotalTimes - iTimesBeforeOpen;
}

int CMagicDoorMgr::GetTotalPayTimes(CPlayerDetailInfo& stPlayerDetail,
        CClanEntry& stClanEntry)
{
    if (stPlayerDetail._stUserClan._stMagicDoor._iLastPayTime <
            stClanEntry._stMagicDoor._iOpenTime)
    {
        //这个暂时只在充能成功后更新到DB
        stPlayerDetail._stUserClan._stMagicDoor._iTimes = 0;
    }

    return stPlayerDetail._stUserClan._stMagicDoor._iTimes;
}

void CMagicDoorMgr::AddTotalPayTimes(CPlayerDetailInfo& stPlayerDetail,
        CClanEntry& stClanEntry)
{
    GetTotalPayTimes(stPlayerDetail, stClanEntry);

    ++stPlayerDetail._stUserClan._stMagicDoor._iTimes;

    stPlayerDetail._stUserClan._stMagicDoor._iLastPayTime =
        CMainCtrl::m_pstMain->m_iNow;
}

//充能
int CMagicDoorMgr::PayContribute(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail,
        CPlayerSnsDetailInfo& stPlayerSnsDetail,
        CPlayerOnlineData& stPlayerOnline, MsgAnsMagicDoor& stAns)
{
    int iTimes = 0;
    int iIndex = 0;

    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerBase._uiGID);
    if (iIndex < 0)
    {
        CT_TRACE(("gid = %u not in any Clan",stPlayerBase._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    //是否魔界传送门场景
    if (!CMainCtrl::m_pstMain->m_stMapViews.IsRoleInMap(
            stMonGroup.GetMapID(), stPlayerDetail._uiGID))
    {
        return ERROR_NOT_FIND_IN_CLAN_MAP;
    }

    //检查是否今天加入的家族
    if (GetCheckJoinDay() &&
        stPlayerDetail._stUserClan.HasJoinedClanBefore() &&
        CTTimeUtils::IsSameDay(stPlayerDetail._stUserClan._iJoinTime,
            CMainCtrl::m_pstMain->m_iNow, 0))
    {
        CT_TRACE(("gid = %u reject pay contribute in join day",
                  stPlayerBase._uiGID));
        return ERROR_REJECT_PAY_CLAN_JOIN_DAY;
    }

    //检查魔界门等级是否已满
    if (stClanEntry._stMagicDoor._chNowLevel >= MAGIC_DOOR_MAX_LEVEL)
    {
        CT_TRACE(("full level, can't pay contribute %u",stPlayerBase._uiGID));
        return ERROR_MAGIC_DOOR_MAX_LEVEL_NOT_CONTRI;
    }

    //充能次数
    iTimes = GetPayContriTimes(stPlayerDetail, true);//取出的是当前已经充能次数

    //加入充能次数限制
    if (iTimes >= MAGIC_DOOR_MAX_PAY_TIMES)
    {
        return ERROR_MAGIC_DOOR_MAX_PAY_TIMES;
    }

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chNowLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    iIndex = FindConsumeConfig(iTimes + 1);
    CT_CHECK(iIndex, ERROR_CONTRIBUTE_TIMES);
    CMagicDoorConsumeCfgData& stConsumeCfgData = GetConsumeConfig(iIndex);

    //检查贡献度是否足够充能
    if (stPlayerSnsDetail._stCommInfo._iContribution <
            stConsumeCfgData.GetSubContribute())
    {
        CT_TRACE(("user(%u) contribute is not enough to pay magic door",
                  stPlayerBase._uiGID));
        return ERROR_NOT_ENOUGH_CONTRIBUTE;
    }

    //贡献度足够充能，减去贡献度，加精力，加充能次数, 
    stPlayerSnsDetail._stCommInfo._iContribution -=
        stConsumeCfgData.GetSubContribute();

    stPlayerDetail._stUserClan._stMagicDoor._stPayContriTimes.Add(1,
        CMainCtrl::m_pstMain->m_iNow);

    AddTotalPayTimes(stPlayerDetail, stClanEntry);

    stPlayerBase._stUserEnergy.AddEnergy(MAGIC_DOOR_ENERGY_INCR,
        CMainCtrl::m_pstMain->m_iNow); 

    //推送角色信息(贡献度和精力)这个操作在sns detail update之后在命令那边执行

    //增加家族魔界门经验
    stClanEntry._stMagicDoor._iExp += MAGIC_DOOR_ADD_EXP_ONE_PAY;
    
    int iLevelUpExp = stLevelCfgData.GetNeedExp();
    while (stClanEntry._stMagicDoor._iExp >= iLevelUpExp)
    {
        stClanEntry._stMagicDoor._iExp -= iLevelUpExp;
        stClanEntry._stMagicDoor._chNowLevel += 1;
        if (stClanEntry._stMagicDoor._chNowLevel > MAGIC_DOOR_MAX_LEVEL)
        {
            CT_WARNING(("role(%u) magic door level(%d) bigger than max(%d)",
                stPlayerBase._uiGID,stClanEntry._stMagicDoor._chNowLevel,
                MAGIC_DOOR_MAX_LEVEL));

            stClanEntry._stMagicDoor._chNowLevel = MAGIC_DOOR_MAX_LEVEL;
            break;
        }

        iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chNowLevel);
        CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
        CMagicDoorLevelCfgData& stLevelCfgDataNew = GetLevelConfig(iIndex);

        iLevelUpExp = stLevelCfgDataNew.GetNeedExp();
    }

    CMagicDoorContriUnit stRankUnit;
    int iOldOrder = -1;
    int iNewOrder = -1;
    int iCurContriCount = GetTotalPayTimes(stPlayerDetail, stClanEntry);

    stRankUnit.SetGID(stPlayerBase._uiGID);
    stRankUnit.SetCount(iCurContriCount);
    stRankUnit.SetRoleName(stPlayerBase._sRoleName());
    stClanEntry._stMagicDoor._astContriList.Update(stRankUnit,
        iOldOrder, iNewOrder);

    NotifyMapUsers(stPlayerDetail, stClanEntry,
        CMD_MAGIC_DOOR_SUB_NOTIFY_MAGIC_INFO, true);

    //取出的是当前已经充能次数
    if (GetPayContriTimes(stPlayerDetail, true) >= MAGIC_DOOR_MAX_PAY_TIMES)
    {
        CMainCtrl::m_pstMain->m_stActMgr.NotifyActListToSelf(
            stPlayerDetail._uiGID);
    }

    return 0;
}

//获取充能排行榜
int CMagicDoorMgr::GetPayContributeRank(CPlayerDetailInfo& stPlayerDetail,
        MsgAnsMagicDoor& stAns)
{
    int iIndex = 0;

    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_TRACE(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    MsgMagicDoorRankInfo* pstRankInfo = stAns.mutable_rank_info();
    if (pstRankInfo)
    {
        pstRankInfo->set_new_circle_pay(
            GetTotalPayTimes(stPlayerDetail, stClanEntry));
    
        for (int i = 0; i < stClanEntry._stMagicDoor._astContriList.Size(); ++i)
        {
            CMagicDoorContriUnit& stUnit =
                stClanEntry._stMagicDoor._astContriList[i];
            MsgMagicDoorRank* pstRankUnit = pstRankInfo->add_door_ranks();
            if (pstRankUnit)
            {
                pstRankUnit->set_gid(stUnit.GetGID());
                pstRankUnit->set_name(stUnit.GetRoleName());
                pstRankUnit->set_seq(i + 1);//由后端加一表示第一名
                pstRankUnit->set_count(stUnit.GetCount());
            }
            else
            {
                CT_ERROR(("MsgMagicDoorRank pb pointer null!"));
            }
        }
    }
    else
    {
        CT_ERROR(("MsgMagicDoorRankInfo pb pointer null!"));
    }

    return 0;
}

//开启魔界传送门
int CMagicDoorMgr::MagicDoorOpen(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail)
{
    int iRet = 0;
    int iIndex = 0;

    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_TRACE(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    int iClanTitle = 0;
    iRet = CMainCtrl::m_pstMain->m_stClanMgr.GetClanTitle(
        stPlayerDetail._uiGID, iClanTitle);
    CT_RETURN(iRet);

    if (CLAN_MEMBER_LEADER != iClanTitle && CLAN_MEMBER_VICE != iClanTitle)
    {
        return ERROR_MAGIC_DOOR_OFFICER_CAN_OPEN;
    }

    //检查是否今天加入的家族
    if (GetCheckJoinDay() &&
        stPlayerDetail._stUserClan.HasJoinedClanBefore() &&
        CTTimeUtils::IsSameDay(stPlayerDetail._stUserClan._iJoinTime,
            CMainCtrl::m_pstMain->m_iNow, 0))
    {
        CT_TRACE(("gid = %u reject open magic door in join day",
                  stPlayerBase._uiGID));
        return ERROR_MAGIC_DOOR_JOIN_DAY_REJECT_OPEN;
    }
     
    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    if (1 == stClanEntry._stMagicDoor._chStatus)
    {
        return ERROR_MAGIC_DOOR_OPEN_ALREADY;
    }

    //检查当天是否开启过
    if (GetCheckJoinDay() && stClanEntry._stMagicDoor._stDailyCounts.Get(
            CMainCtrl::m_pstMain->m_iNow) >= MAGIC_DOOR_OPEN_TIME_PER_DAY)
    {
        return ERROR_MAGICDOOR_ONETIMES_PER_DAY;
    }

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chNowLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    //设置魔界传送门数据
    stClanEntry._stMagicDoor._chStatus = 1;
    stClanEntry._stMagicDoor._chOpenLevel =
        stClanEntry._stMagicDoor._chNowLevel;
    stClanEntry._stMagicDoor._chNowLevel = 0;
    stClanEntry._stMagicDoor._iExp = 0;
    stClanEntry._stMagicDoor._iOpenTime = CMainCtrl::m_pstMain->m_iNow;
    stClanEntry._stMagicDoor._stDailyCounts.Add(1,
        CMainCtrl::m_pstMain->m_iNow);

    //添加活动到期结束定时器
    CActTimer stActTimer;
    stActTimer.SetType(CActTimer::ACT_TIMER_MAGIC_DOOR_CLOSE);
    stActTimer.SetDelTime(
        CMainCtrl::m_pstMain->m_iNow + MAGIC_DOOR_TIME_AFTER_OPEN);
    stActTimer.SetData(stClanEntry._uiClanId);
    CMainCtrl::m_pstMain->m_stActMgr.AddActTimer(stActTimer);

    //奖励充能榜前三名礼包
    iRet = AwardToContributeRank(stPlayerDetail._stUserClan._uiClanId);
    if (iRet)
    {
        CT_WARNING(("clan(%u) award to contribute rank error(%d)",
            stPlayerDetail._stUserClan._uiClanId,iRet));
    }

    //开启时候 全员奖励贡献度
    if (stLevelCfgData.GetContributeAward() > 0)
    {
        AwardToAllClanMembers(stPlayerDetail._stUserClan._uiClanId,
            stLevelCfgData.GetContributeAward());
    }

    //清空充能榜
    stClanEntry._stMagicDoor._astContriList.Clear();

    //初始化怪物列表
    iRet = InitMagicDoorMonsterInfo(stPlayerDetail);
    CT_RETURN(iRet);

    //本身是星门开启的响应不需要下发给自己
    NotifyMapUsers(stPlayerDetail, stClanEntry,
        CMD_MAGIC_DOOR_SUB_NOTIFY_OPEN_DOOR, false);

    NotifyActInfoToAllClanMembers(stClanEntry);

    return 0;
}

//活动到期结束处理逻辑
int CMagicDoorMgr::TimeUpCloseMagicDoor(unsigned int uiClanID)
{
    int iIndex = 0;

    //检查家族是否存在
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash.HashFind(
        uiClanID);
    if (iIndex < 0)
    {
        CT_WARNING(("clan(%u) member not exist!",uiClanID));
        return ERROR_CLAN_NOT_EXIST;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    //检查魔界门的状态是否开启
    if (stClanEntry._stMagicDoor._chStatus != 1)
    {
        return ERROR_MAGIC_DOOR_IS_CLOSED;
    }

    CloseMagicDoor(stClanEntry, 0);

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    PBMsgHead stMsgHead;
    stMsgHead.set_version(0);
    stMsgHead.set_time(CMainCtrl::m_pstMain->m_iNow);
    stMsgHead.set_msgact(0);
    stMsgHead.set_msgid(ID_MAIN_MAGIC_DOOR);
    stMsgHead.set_msgret(0);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    MsgAnsMagicDoor stAns;
    bool bInitMonsterInfo = false;
    for (int i = 0; i < stClanEntry._astClanMember.Size(); ++i)
    {
        iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(
            stClanEntry._astClanMember[i]._uiGid);
        if (iIndex >= 0)
        {
            CPlayerDetailInfo& stPlayerDetailTmp =
                CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

            GetMagicDoorMonsterInfo(stPlayerDetailTmp, stAns);
            bInitMonsterInfo = true;
            break;
        }
    }

    if (!bInitMonsterInfo)
    {
        CMainCtrl::m_pstMain->FlushSendCache();
        CT_WARNING(("clan(%u %s) no one member get detail data",
            stClanEntry._uiClanId,stClanEntry._szName()));
        return 0;
    }

    for (int i = 0; i < stClanEntry._astClanMember.Size(); ++i)
    {
        if (!CMainCtrl::m_pstMain->m_stPlayerOnline.CheckOnline(
                stClanEntry._astClanMember[i]._uiGid))
        {
            CT_TRACE(("clan(%u %s) notify magic door act member(%u) offline",
                stClanEntry._uiClanId,stClanEntry._szName(),
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }

        iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(
            stClanEntry._astClanMember[i]._uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("notify magic door user(%u) but no online data!",
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }
        CPlayerOnlineData& stPlayerOnline =
            CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

        if (stMonGroup.GetMapID() != stPlayerOnline._uiNowMapID)
        {
            continue;
        }

        stAns.set_gid(stClanEntry._astClanMember[i]._uiGid);
        stAns.set_req_type(CMD_MAGIC_DOOR_SUB_GET_MONSTER);

        CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
        
        CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead,
            CMainCtrl::m_pstMain->m_stEncodeBuf);
        CMainCtrl::m_pstMain->EncodePBMsg(stAns,
            CMainCtrl::m_pstMain->m_stEncodeBuf);

        CMainCtrl::m_pstMain->NotifyOnlineUser(
            stClanEntry._astClanMember[i]._uiGid,
            CMainCtrl::m_pstMain->m_stEncodeBuf);
    }

    CMainCtrl::m_pstMain->FlushSendCache();

    return 0;
}

int CMagicDoorMgr::CloseMagicDoor(CClanEntry& stClanEntry, int iStatus)
{
    stClanEntry._stMagicDoor._chStatus = 0;
    stClanEntry._stMagicDoor._chOpenLevel = 0;
    stClanEntry._stMagicDoor._iWorldLevel = 0;
    stClanEntry._stMagicDoor._astMonsterList.Clear();

    //更新家族数据 在外面命令执行

    NotifyActCloseTipsToAllClanMembers(stClanEntry, iStatus);

    NotifyActInfoToAllClanMembers(stClanEntry);

    return 0;
}

int CMagicDoorMgr::NotifyActInfoToAllClanMembers(unsigned int uiClanID)
{
    int iIndex = 0;

    //检查家族是否存在
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash.HashFind(
        uiClanID);
    if (iIndex < 0)
    {
        CT_WARNING(("clan(%u) member not exist!",uiClanID));
        return ERROR_CLAN_NOT_EXIST;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    return NotifyActInfoToAllClanMembers(stClanEntry);
}

//下发活动列表给在线家族成员
int CMagicDoorMgr::NotifyActInfoToAllClanMembers(CClanEntry& stClanEntry)
{
    for (int i = 0; i < stClanEntry._astClanMember.Size(); i++)
    {
        if (!CMainCtrl::m_pstMain->m_stPlayerOnline.CheckOnline(
                stClanEntry._astClanMember[i]._uiGid))
        {
            CT_TRACE(("clan(%u %s) notify magic door act member(%u) offline",
                stClanEntry._uiClanId,stClanEntry._szName(),
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }

        CMainCtrl::m_pstMain->m_stActMgr.NotifyActListToSelf(
            stClanEntry._astClanMember[i]._uiGid);
    }
    return 0;
}

//下发活动结束消息给在线家族成员
int CMagicDoorMgr::NotifyActCloseTipsToAllClanMembers(CClanEntry& stClanEntry,
        int iCloseStat)
{
    CTSizeString<ROLENAME_LEN> szNameStr;
    MsgTips stTips;
    stTips.set_type(TIPS_MAGIC_DOOR_CLOSE);
    szNameStr.Set("%d",iCloseStat);//是否击杀所有怪物 0 否 1 是
    stTips.add_tip_argument(szNameStr());

    PBMsgHead stMsgHead;
    stMsgHead.set_version(0);
    stMsgHead.set_time(CMainCtrl::m_pstMain->m_iNow);
    stMsgHead.set_msgact(0);
    stMsgHead.set_msgid(ID_MAIN_TIPS);
    stMsgHead.set_msgret(0);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
    CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead,
        CMainCtrl::m_pstMain->m_stEncodeBuf);
    CMainCtrl::m_pstMain->EncodePBMsg(stTips,
        CMainCtrl::m_pstMain->m_stEncodeBuf);

    for (int i = 0; i < stClanEntry._astClanMember.Size(); i++)
    {
        if (!CMainCtrl::m_pstMain->m_stPlayerOnline.CheckOnline(
                stClanEntry._astClanMember[i]._uiGid))
        {
            CT_TRACE(("clan(%u %s) notify magic door act member(%u) offline",
                stClanEntry._uiClanId,stClanEntry._szName(),
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }

        CMainCtrl::m_pstMain->NotifyOnlineUser(
            stClanEntry._astClanMember[i]._uiGid,
            CMainCtrl::m_pstMain->m_stEncodeBuf);
    }

    return 0;
}

//奖励充能榜前三名礼包
int CMagicDoorMgr::AwardToContributeRank(unsigned int uiClanID)
{
    int iIndex = 0;

    //检查家族是否存在
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash.HashFind(
        uiClanID);
    if (iIndex < 0)
    {
        CT_WARNING(("clan(%u) member not exist!",uiClanID));
        return ERROR_CLAN_NOT_EXIST;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chOpenLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    unsigned int uiGiftID = 0;
    for (int i = 0; i < stClanEntry._stMagicDoor._astContriList.Size() &&
            i < stLevelCfgData.GetContriGiftSize(); ++i)
    {
        CMagicDoorContriUnit& stUnit =
            stClanEntry._stMagicDoor._astContriList[i];

        uiGiftID = (unsigned int)stLevelCfgData.GetContriGiftID(i);

        CT_TRACE(("clan(%u %s) contribute rank(%d) role(%u) gift(%u)",
                  uiClanID,stClanEntry._szName.Get(),i,stUnit.GetGID(),
                  uiGiftID));
        if (uiGiftID > 0)
        {
            CMainCtrl::m_pstMain->m_stItemMgr.DropBonus(OSS_MODULE_DOOR,
                stUnit.GetGID(), uiGiftID, 1);
        }
    }

    return 0;
}

//奖励家族成员贡献度
int CMagicDoorMgr::AwardToAllClanMembers(unsigned int uiClanID,
        int iContributeAward)
{
    int iIndex = 0;

    //检查家族是否存在
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash.HashFind(
        uiClanID);
    if (iIndex < 0)
    {
        CT_WARNING(("clan(%u) member not exist!",uiClanID));
        return ERROR_CLAN_NOT_EXIST;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    CDropItem  stDropItem;
    CDropItemData stDropItemData;

    stDropItemData._ucItemType = ITEM_TYPE_CONTRIBUTION;
    stDropItemData._iItemCount = iContributeAward;
    stDropItem.Drop(stDropItemData);
    stDropItem.SetOssModule(OSS_MODULE_DOOR);
    for (int i = 0; i < stClanEntry._astClanMember.Size(); i++)
    {
        CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL,
            stClanEntry._astClanMember[i]._uiGid, stDropItem);
    }

    return 0;
}

//获取怪物信息
int CMagicDoorMgr::GetMagicDoorMonsterInfo(CPlayerDetailInfo& stPlayerDetail,
        MsgAnsMagicDoor& stAns)
{
    int iIndex = 0;

    //此接口尽量不要与个体绑定调用方只想取出家族的怪物列表 --byronwei
    
    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    unsigned int uiGroupID = 0;
    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    for (int i = 0; i < stClanEntry._stMagicDoor._astMonsterList.Size(); ++i)
    {
        CMagicDoorMonUnit& stMonsterUnit =
            stClanEntry._stMagicDoor._astMonsterList[i];

        MsgMagicDoorBoss* pstMonsterUnit = stAns.add_boss_info();
        if (!pstMonsterUnit){CT_WARNING(("pb pointer null!"));continue;}

        uiGroupID = stMonGroup.GetNormalID();
        if (stMonsterUnit.IsSpecialMon())
        {
            uiGroupID = stMonGroup.GetSpecialID();
        }

        pstMonsterUnit->set_group_id(uiGroupID);
        pstMonsterUnit->set_max_blood(stMonsterUnit.GetMaxHP());
        pstMonsterUnit->set_cur_blood(stMonsterUnit.GetNowHP());
        pstMonsterUnit->set_index(i);
    }

    return 0;
}

CMagicDoorMonGroup& CMagicDoorMgr::GetMagicDoorMonGroup()
{
    int iIndex = 0;
    if (_stMonGroup.GetNormalID() <= 0)
    {
        iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(
            ACT_ID_MAGIC_DOOR);
        if (iIndex < 0)
        {
            CT_ERROR(("magic door act(%d) config empty!",
                      ACT_ID_MAGIC_DOOR));
            return _stMonGroup;
        }

        CActCfgData& stActCfgData =
            CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

        iIndex = CMainCtrl::m_pstMain->m_stSceneMgr.FindSceneCfg(
            stActCfgData.GetSceneID());
        if (iIndex < 0)
        {
            CT_ERROR(("magic door scene(%d) config in act(%d) empty!",
                      stActCfgData.GetSceneID(),ACT_ID_MAGIC_DOOR));
            return _stMonGroup;
        }

        CSceneCfgData& stSceneCfgData =
            CMainCtrl::m_pstMain->m_stSceneMgr.GetSceneCfg(iIndex);

        _stMonGroup.SetMapID(stSceneCfgData.GetMapID());
        _stMonGroup.SetNormalID(stSceneCfgData.GetMonGroupID());
        _stMonGroup.SetSpecialID(stSceneCfgData.GetLeftGroupID());
    }

    return _stMonGroup;
}

int CMagicDoorMgr::InitMagicDoorMonsterInfo(CPlayerDetailInfo& stPlayerDetail)
{
    int iRet = 0;
    int iIndex = 0;
    bool bAddSpecialMon = false;

    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_TRACE(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chOpenLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    stClanEntry._stMagicDoor._astMonsterList.Clear();

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    if (CT_RANDOM_NUM->GetRand(COMM_MOD) < stLevelCfgData.GetSpecialBoss())
    {
        bAddSpecialMon = true;
    }

    stClanEntry._stMagicDoor._iWorldLevel =
        CMainCtrl::m_pstMain->GetWorldLevel();

    CMagicDoorMonUnit stMonsterUnit;
    CMonsterGroupConfigData stMonsterGroup;

    //特殊BOSS
    if (bAddSpecialMon)
    {
        iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
            stMonGroup.GetSpecialID(), stClanEntry._stMagicDoor._iWorldLevel,
            stMonsterGroup);
        CT_RETURN(iRet);

        stMonsterUnit.SetNowHP(
         stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
        stMonsterUnit.SetMaxHP(
         stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
        stMonsterUnit.SetSpecMon(1);

        stClanEntry._stMagicDoor._astMonsterList.AddOneItem(stMonsterUnit);
    }

    //普通BOSS
    iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
        stMonGroup.GetNormalID(), stClanEntry._stMagicDoor._iWorldLevel,
        stMonsterGroup);
    CT_RETURN(iRet);

    stMonsterUnit.SetNowHP(
     stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetMaxHP(
     stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetSpecMon(0);

    for (int i = 0; i < stLevelCfgData.GetBossNum(); ++i)
    {
        stClanEntry._stMagicDoor._astMonsterList.AddOneItem(stMonsterUnit);
    }

    return 0;
}

//触发战斗
int CMagicDoorMgr::GetMagicDoorBattleCamera(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CPlayerCacheData& stPlayerCache, MsgReqMagicDoor& stReq,
        MsgAnsMagicDoor& stAns)
{
    int iRet = 0;
    int iIndex = 0;
    int iMonIndex = stReq.index();
    unsigned int uiMonGroupID = 0;
    
    //家族的数据
    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u not in any Clan",stPlayerDetail._uiGID));
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        CT_ERROR(("clan entry id(%u) role(%u) clan detail user clan id(%u)",
                  stClanEntry._uiClanId,stPlayerDetail._uiGID,
                  stPlayerDetail._stUserClan._uiClanId));
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    //是否魔界传送门场景
    if (!CMainCtrl::m_pstMain->m_stMapViews.IsRoleInMap(
            stMonGroup.GetMapID(), stPlayerDetail._uiGID))
    {
        return ERROR_NOT_FIND_IN_CLAN_MAP;
    }

    //检查是否今天加入的家族
    if (GetCheckJoinDay() &&
        stPlayerDetail._stUserClan.HasJoinedClanBefore() &&
        CTTimeUtils::IsSameDay(stPlayerDetail._stUserClan._iJoinTime,
            CMainCtrl::m_pstMain->m_iNow, 0))
    {
        CT_TRACE(("gid = %u reject magic door battle in join day",
                  stPlayerBase._uiGID));
        return ERROR_MAGIC_DOOR_JOIN_DAY_REJECT_BATTLE;
    }

    CheckMagicDoorDataZero(stClanEntry);
    CheckPayContriTimes(stPlayerDetail, stClanEntry);

    //检查魔界门的状态是否开启
    if (stClanEntry._stMagicDoor._chStatus != 1)
    {
        return ERROR_MAGIC_DOOR_IS_CLOSED;
    }

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_MAGIC_DOOR);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);

    CActCfgData& stActCfgData =
        CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MAGIC_DOOR);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
                stPlayerCache, iIndex);

        //战斗等待状态到期 先不主动清除 只判断时间
        if (stStatusUnit.GetEndTime() > CMainCtrl::m_pstMain->m_iNow)
        {
            return ERROR_STATUS_IN_FIGHT_CD;
        }
    }

    if (iMonIndex < 0 ||
        iMonIndex >= stClanEntry._stMagicDoor._astMonsterList.Size())
    {
        return ERROR_MAGIC_NOT_THIS_MONSTER_GROUP;
    }

    if (stClanEntry._stMagicDoor._astMonsterList[iMonIndex].GetNowHP() <= 0)
    {
        return ERROR_MAGIC_BOSS_IS_DIED;
    }

    SetAtkValue(0);
    SetMonNowHP(stClanEntry._stMagicDoor._astMonsterList[iMonIndex].GetNowHP());

    uiMonGroupID = stMonGroup.GetNormalID();
    if (stClanEntry._stMagicDoor._astMonsterList[iMonIndex].IsSpecialMon())
    {
        uiMonGroupID = stMonGroup.GetSpecialID();
    }

    CMonsterGroupConfigData stMonsterGroup;
    iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
        uiMonGroupID, stClanEntry._stMagicDoor._iWorldLevel, stMonsterGroup);
    CT_RETURN(iRet);

    MsgBattleResult* pstBattleResult = stAns.mutable_battle_result();
    if (!pstBattleResult) {return RET_SYS_NULL_POINTER;}//简单保护

    iRet = CMainCtrl::m_pstMain->m_stBattleMgr.DealWorldBoss(stPlayerBase,
        stPlayerDetail, stPlayerOnline, stMonsterGroup, *pstBattleResult,
        stActCfgData.GetType());
    CT_RETURN(iRet);

	if (stReq.has_battle_ext_info())
	{
		(*pstBattleResult->mutable_battle_ext_info()) =
            stReq.battle_ext_info();
	}

    for (int i = 0; i <
            CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRoleCount(); ++i)
    {
        CBattleRole& stBattleObj =
            CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRole(i);
        if (stBattleObj.IsMonsterObject())
        {
            SetAtkValue(GetMonNowHP() - stBattleObj.GetHP());
            stClanEntry._stMagicDoor._astMonsterList[iMonIndex].SetNowHP(
                stBattleObj.GetHP());
            break;
        }
    }

    for (int i = 0; i <
            CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRoleCount(); ++i)
    {
        CBattleRole& stBattleObj =
            CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRole(i);
        if (stBattleObj.IsPlayerObject())
        {
            iRet = DealPlayerAfterBattle(stPlayerCache, stClanEntry, stAns,
                stClanEntry._stMagicDoor._astMonsterList[iMonIndex],
                pstBattleResult->result());
            if (iRet){CT_ERROR(("Deal player after battle error(%d)!",iRet));}

            iRet = DealClanAfterBattle(stPlayerBase, stPlayerDetail,
                stClanEntry);
            if (iRet){CT_ERROR(("Deal player after battle error(%d)!",iRet));}

            break;
        }
    }

    return iRet;
}

//修正战斗开始前数据
int CMagicDoorMgr::ReviseBeforeBattle(int iBossBattleID)
{
    if (iBossBattleID < 0 ||
        iBossBattleID >=
            CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRoleCount())
    {
        return ERROR_BATTLE_GRID_ID;
    }

    CBattleRole& stBattleRole =
        CMainCtrl::m_pstMain->m_stBattleMgr.GetBattleRole(iBossBattleID);

    stBattleRole.SetHP(GetMonNowHP());

    return 0;
}

int CMagicDoorMgr::DealPlayerAfterBattle(CPlayerCacheData& stPlayerCache,
        CClanEntry& stClanEntry, MsgAnsMagicDoor& stAns,
        CMagicDoorMonUnit& stMonsterUnit, int iBattleResult)
{
    int iRet = 0;
    int iIndex = 0;

    //奖励结算
    MagicDoorRoleAward(stPlayerCache, stClanEntry, stAns, stMonsterUnit);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MAGIC_DOOR);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    //如果怪物没有死亡而主角死亡则施加战斗冷却
    if (BATTLE_RESULT_WIN != iBattleResult)
    {
        //战斗冷却没有叠加层数 直接修改到期时间
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.AddStatus(
            stPlayerCache, stActStatusCfg.GetCoolingID(),
            CMainCtrl::m_pstMain->m_iNow + MAGIC_DOOR_BATTLE_DEAD_CD_TIME,
            ACT_ID_MAGIC_DOOR, true);
        if (iRet) {CT_ERROR(("role add fight cool status error(%d)",iRet));}
    }

    return 0;
}

int CMagicDoorMgr::MagicDoorRoleAward(CPlayerCacheData& stPlayerCache,
        CClanEntry& stClanEntry, MsgAnsMagicDoor& stAns,
        CMagicDoorMonUnit& stMonsterUnit)
{
    int iRet = 0;
    int iIndex = 0;
    int64 i64ValueTmp = 0;

    if (GetAtkValue() <= 0 || stMonsterUnit.GetMaxHP() <= 0)
    {
        return 0;
    }

    i64ValueTmp = INT64_1 * GetAtkValue() * BATTLE_RATE_SKILL_PERCENT;
    i64ValueTmp /= stMonsterUnit.GetMaxHP();
    int iAttackValue = (int)(i64ValueTmp);
    if (iAttackValue <= 0)
    {
        iAttackValue = 1;
    }

    iIndex = CMainCtrl::m_pstMain->m_stWorldBossMgr.FindAttackConfig(
        iAttackValue);
    if (iIndex < 0)
    {
        CT_ERROR(("boss attack hp(%d) max hp(%d) attack id(%d) but cfg empty",
                  GetAtkValue(),stMonsterUnit.GetMaxHP(),iAttackValue));
        return 0;
    }

    CWorldBossCfgAttack& stAttackCfg =
        CMainCtrl::m_pstMain->m_stWorldBossMgr.GetAttackConfig(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stWorldBossMgr.FindRewardConfig(
        stClanEntry._stMagicDoor._iWorldLevel);
    if (iIndex < 0)
    {
        CT_ERROR(("magic door world level(%d) cfg empty",
            stClanEntry._stMagicDoor._iWorldLevel));
        return 0;
    }

    CWorldBossCfgReward& stRewardCfg =
        CMainCtrl::m_pstMain->m_stWorldBossMgr.GetRewardConfig(iIndex);

    i64ValueTmp = INT64_1 * stRewardCfg.GetMagicDoorReputation() *
        stAttackCfg.GetReputationBase();
    i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
    int iReputation = (int)(i64ValueTmp);

    i64ValueTmp = INT64_1 * stRewardCfg.GetMagicDoorExp() *
        stAttackCfg.GetExpBase();
    i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
    int iBattleExp = (int)(i64ValueTmp);

    i64ValueTmp = INT64_1 * stRewardCfg.GetMagicDoorContribu() *
        stAttackCfg.GetContribuBase();
    i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
    int iContribu = (int)(i64ValueTmp);

    i64ValueTmp = INT64_1 * stRewardCfg.GetMagicDoorSilver() *
        stAttackCfg.GetSilverBase();
    i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
    int iSilver = (int)(i64ValueTmp);

    unsigned int uiGiftID = 0;
    if (stMonsterUnit.GetNowHP() <= 0)//死亡奖励礼包
    {
        uiGiftID = stRewardCfg.GetMagicDoorKillGift();
        if (stMonsterUnit.IsSpecialMon())
        {
            uiGiftID = stRewardCfg.GetMagicDoorKillSpeGift();
        }
    }

    CDropItem stDropItem;
    if (uiGiftID > 0)
    {
        iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetGiftItem(uiGiftID,
            stPlayerCache._uiGID, stDropItem, false);
        if (iRet)
        {
            CT_WARNING(("get role(%u) gift(%u) item ret(%d)",
                stPlayerCache._uiGID,uiGiftID,iRet));
        }
    }

    MagicDoorRoleAwardItem(stPlayerCache._uiGID, iReputation, iBattleExp,
        iContribu, iSilver, stDropItem);

    stDropItem.GetPBMsg(stPlayerCache._uiGID,*(stAns.mutable_battle_award()));

    CTSizeString<ROLENAME_LEN> szNameStr;
    MsgTips stTips;
    stTips.set_type(TIPS_MAGIC_DOOR_BONUS);
    szNameStr.Set("%d",GetAtkValue());//伤害
    stTips.add_tip_argument(szNameStr());
    stDropItem.GetPBMsg(stPlayerCache._uiGID, *(stTips.mutable_bonus()));

    CMainCtrl::m_pstMain->NotifyOnlineUser(stPlayerCache._uiGID, ID_MAIN_TIPS,
        stTips, false);

    return 0;
}

int CMagicDoorMgr::MagicDoorRoleAwardItem(unsigned int uiGID, int iRepu,
        int iExp, int iContri, int iSilver, CDropItem& stDropItem)
{
    if (iRepu > 0)
    {
        stDropItem.DropItem(ITEM_TYPE_REPUTATION, iRepu);
    }

    if (iExp > 0)
    {
        stDropItem.DropItem(ITEM_TYPE_EXP, iExp);
    }

    if (iContri > 0)
    {
        stDropItem.DropItem(ITEM_TYPE_CONTRIBUTION, iContri);
    }

    if (iSilver > 0)
    {
        stDropItem.DropItem(ITEM_TYPE_SILVER, iSilver);
    }

    if (stDropItem.Size() > 0)
    {
        stDropItem.SetOssModule(OSS_MODULE_DOOR);
        //CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, uiGID, stDropItem);
        CMainCtrl::m_pstMain->m_stItemMgr.DropItemEx(NULL, uiGID, stDropItem);
    }

    return 0;
}

int CMagicDoorMgr::DealClanAfterBattle(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CClanEntry& stClanEntry)
{    
    int iIndex = 0;

    if (GetAtkValue() > 0)
    {
        NotifyMapUsers(stPlayerDetail, stClanEntry,
            CMD_MAGIC_DOOR_SUB_NOTIFY_MONSTER_INFO, true);
    }

    if (stClanEntry._stMagicDoor._astMonsterList.Size() <= 0)
    {
        return 0;
    }

    for (int i = 0; i < stClanEntry._stMagicDoor._astMonsterList.Size(); ++i)
    {
        if (stClanEntry._stMagicDoor._astMonsterList[i].GetNowHP() > 0)
        {
            return 0;//怪物没有全部杀死 不发放家族公共礼包
        }
    }

    //下发家族共享礼包 并设置状态 清空怪物

    iIndex = FindLevelConfig(stClanEntry._stMagicDoor._chOpenLevel);
    CT_CHECK(iIndex, ERROR_MAGIC_DOOR_LEVEL);
    CMagicDoorLevelCfgData& stLevelCfgData = GetLevelConfig(iIndex);

    CDropItem stClanItem;
    CDropItemData stData;
    for (int i = 0; i < stLevelCfgData.GetActGiftSize(); ++i)
    {
        CLevelGiftUnit& stGiftUnit = stLevelCfgData.GetActGift(i);
        if (stGiftUnit.GetGiftID() > 0 && stGiftUnit.GetGiftNum() > 0)
        {
            stData._ucItemType = ITEM_TYPE_GIFT;
            stData._usItemConfigID = stGiftUnit.GetGiftID();
            stData._iItemCount = stGiftUnit.GetGiftNum();

            stClanItem.Drop(stData);
        }
    }

    if (stClanItem.Size() > 0)
    {
        stClanItem.SetOssModule(OSS_MODULE_DOOR);
        CMainCtrl::m_pstMain->m_stClanMgr.AddItem(stClanEntry._uiClanId, stClanItem);
    }

    CloseMagicDoor(stClanEntry, 1);

    return 0;
}

int CMagicDoorMgr::NotifyMapUsers(CPlayerDetailInfo& stPlayerDetail,
        CClanEntry& stClanEntry, int iSubCmd, bool bNotifySelf)
{
    int iIndex = 0;
    int iAnsCmd = 0;
    int iInnerCmd = 0;

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    //若除gid外响应包还存在个体差异性则需要数据准备
    //但是因为各个个体gid存在差异需要独自PB编码
    MsgAnsMagicDoor stAns;
    stAns.set_gid(stPlayerDetail._uiGID);

    switch (iSubCmd)
    {
    case CMD_MAGIC_DOOR_SUB_NOTIFY_MAGIC_INFO:
        {
            stAns.set_req_type(CMD_MAGIC_DOOR_SUB_GET_INFO);
            GetMagicDoorInfo(stPlayerDetail, stAns);

            iAnsCmd = CMD_MAGIC_DOOR_SUB_GET_INFO;

            //注意：不是CMD_MAGIC_DOOR_SUB_GET_INFO
            iInnerCmd = CMD_MAGIC_DOOR_SUB_NOTIFY_MAGIC_INFO;
        }
        break;
    case CMD_MAGIC_DOOR_SUB_NOTIFY_OPEN_DOOR:
        {
            stAns.set_req_type(CMD_MAGIC_DOOR_SUB_OPEN_DOOR);

            iAnsCmd = CMD_MAGIC_DOOR_SUB_OPEN_DOOR;

            //注意：不是CMD_MAGIC_DOOR_SUB_OPEN_DOOR
            iInnerCmd = CMD_MAGIC_DOOR_SUB_NOTIFY_OPEN_DOOR;
        }
        break;
    case CMD_MAGIC_DOOR_SUB_NOTIFY_MONSTER_INFO:
        {
            stAns.set_req_type(CMD_MAGIC_DOOR_SUB_GET_MONSTER);
            GetMagicDoorMonsterInfo(stPlayerDetail, stAns);

            iAnsCmd = CMD_MAGIC_DOOR_SUB_GET_MONSTER;

            //注意：不是CMD_MAGIC_DOOR_SUB_GET_INFO
            iInnerCmd = CMD_MAGIC_DOOR_SUB_NOTIFY_MONSTER_INFO;
        }
        break;
    default:
        {
            CT_WARNING(("magic door notify users unknow sub cmd(%d)",iSubCmd));
            return 0;
        }
    }

    PBMsgHead stMsgHead;
    stMsgHead.set_version(0);
    stMsgHead.set_time(CMainCtrl::m_pstMain->m_iNow);
    stMsgHead.set_msgact(0);
    stMsgHead.set_msgid(ID_MAIN_MAGIC_DOOR);
    stMsgHead.set_msgret(0);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (bNotifySelf)
    {
        CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
        
        CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead,
            CMainCtrl::m_pstMain->m_stEncodeBuf);
        CMainCtrl::m_pstMain->EncodePBMsg(stAns,
            CMainCtrl::m_pstMain->m_stEncodeBuf);

        CMainCtrl::m_pstMain->NotifyOnlineUser(stPlayerDetail._uiGID,
            CMainCtrl::m_pstMain->m_stEncodeBuf);
    }

    MsgReqMagicDoor stReqTmp;
    for (int i = 0; i < stClanEntry._astClanMember.Size(); ++i)
    {
        if (stClanEntry._astClanMember[i]._uiGid == stPlayerDetail._uiGID)
        {
            continue;
        }

        if (!CMainCtrl::m_pstMain->m_stPlayerOnline.CheckOnline(
                stClanEntry._astClanMember[i]._uiGid))
        {
            CT_TRACE(("clan(%u %s) notify magic door act member(%u) offline",
                stClanEntry._uiClanId,stClanEntry._szName(),
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }

        iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(
            stClanEntry._astClanMember[i]._uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("notify magic door user(%u) but no online data!",
                stClanEntry._astClanMember[i]._uiGid));
            continue;
        }
        CPlayerOnlineData& stPlayerOnline =
            CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

        if (stMonGroup.GetMapID() != stPlayerOnline._uiNowMapID)
        {
            continue;
        }

        if (CMD_MAGIC_DOOR_SUB_GET_INFO == iAnsCmd)
        {
            iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(
                stClanEntry._astClanMember[i]._uiGid);
            if (iIndex >= 0)
            {
                CPlayerDetailInfo& stPlayerDetailTmp =
                    CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

                stAns.Clear();
                stAns.set_gid(stClanEntry._astClanMember[i]._uiGid);
                stAns.set_req_type(iAnsCmd);

                GetMagicDoorInfo(stPlayerDetailTmp, stAns);

                CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
                
                CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead,
                    CMainCtrl::m_pstMain->m_stEncodeBuf);
                CMainCtrl::m_pstMain->EncodePBMsg(stAns,
                    CMainCtrl::m_pstMain->m_stEncodeBuf);

                CMainCtrl::m_pstMain->NotifyOnlineUser(
                    stClanEntry._astClanMember[i]._uiGid,
                    CMainCtrl::m_pstMain->m_stEncodeBuf);
            }
            else
            {
                stReqTmp.Clear();
                stReqTmp.set_gid(stClanEntry._astClanMember[i]._uiGid);
                stReqTmp.set_req_type(iInnerCmd);
                CMainCtrl::m_pstMain->SendInnerCmd(
                    stClanEntry._astClanMember[i]._uiGid, ID_MAIN_MAGIC_DOOR,
                    stReqTmp, true);
            }
        }
        else if (CMD_MAGIC_DOOR_SUB_OPEN_DOOR == iAnsCmd ||
                    CMD_MAGIC_DOOR_SUB_GET_MONSTER == iAnsCmd)
        {
            stAns.set_gid(stClanEntry._astClanMember[i]._uiGid);
            stAns.set_req_type(iAnsCmd);

            CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
            
            CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead,
                CMainCtrl::m_pstMain->m_stEncodeBuf);
            CMainCtrl::m_pstMain->EncodePBMsg(stAns,
                CMainCtrl::m_pstMain->m_stEncodeBuf);

            CMainCtrl::m_pstMain->NotifyOnlineUser(
                stClanEntry._astClanMember[i]._uiGid,
                CMainCtrl::m_pstMain->m_stEncodeBuf);
        }
        else
        {
            CT_ERROR(("iAnsCmd(%d) unknow!",iAnsCmd));
            break;
        }
    }

    return 0;
}

int CMagicDoorMgr::NotifyAllClanUsers()
{
    int iRet = 0;
    int iIndex = 0;

    MsgReqMagicDoor stReqTmp;
    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    const CTArray<unsigned int, MAX_PLAYER_ONLINE>& astAllUsers =
        CMainCtrl::m_pstMain->m_stPlayerOnline.GetAllOnlineUser();

    CT_TRACE(("act change notify all online user(%d)!",astAllUsers.Size()));

    for (int i = 0; i < astAllUsers.Size(); ++i)
    {
        iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(
            astAllUsers[i]);
        if (iIndex < 0)
        {
            CT_ERROR(("notify magic door user(%u) but no online data!",
                astAllUsers[i]));
            continue;
        }

        CPlayerOnlineData& stPlayerOnline =
            CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

        if (stMonGroup.GetMapID() != stPlayerOnline._uiNowMapID)
        {
            continue;
        }

        stReqTmp.set_gid(astAllUsers[i]);
        stReqTmp.set_req_type(CMD_MAGIC_DOOR_SUB_NOTIFY_MAGIC_INFO);
        iRet = CMainCtrl::m_pstMain->SendInnerCmd(astAllUsers[i],
            ID_MAIN_MAGIC_DOOR, stReqTmp, true);

        if (iRet)
        {
            CT_ERROR(("send role(%u) inner cmd(%d) error(%d)",astAllUsers[i],
                ID_MAIN_MAGIC_DOOR,iRet));
        }
    }

    CMainCtrl::m_pstMain->FlushSendCache();

    return 0;
}

int CMagicDoorMgr::GMSetMonsterHP(CPlayerDetailInfo& stPlayerDetail, int iNewHP,
        int iMonIndex)
{
    int iIndex = 0;

    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

#define MAGIC_DOOR_MONSTER_INDEX_CHECK_JOIN_DAY 1000
    if (MAGIC_DOOR_MONSTER_INDEX_CHECK_JOIN_DAY == iMonIndex)
    {
        SetCheckJoinDay(iNewHP);
        return 0;
    }

    if (iMonIndex < 0 ||
        iMonIndex >= stClanEntry._stMagicDoor._astMonsterList.Size())
    {
        return ERROR_MAGIC_NOT_THIS_MONSTER_GROUP;
    }

    if (stClanEntry._stMagicDoor._astMonsterList[iMonIndex].GetNowHP() <= 0)
    {
        return ERROR_MAGIC_BOSS_IS_DIED;
    }

    stClanEntry._stMagicDoor._astMonsterList[iMonIndex].SetNowHP(iNewHP);

    return 0;
}

int CMagicDoorMgr::GMDealMagicDoor(CPlayerDetailInfo& stPlayerDetail,
        CPlayerSnsDetailInfo& stPlayerSnsDetail, MsgReqGMPlayer& stReq,
        MsgAnsGMPlayer& stAns)
{
    int iIndex = 0;
    CTSizeString<MAX_BATTLE_NAME_BUFF> szNameStr;

    iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(
        stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        return ERROR_MAGIC_DOOR_NOT_IN_CLAN;
    }
    CClanEntry& stClanEntry =
        CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

    if (stPlayerDetail._stUserClan._uiClanId != stClanEntry._uiClanId)
    {
        return ERROR_CLAN_MEMBER_NOT_EXIST;
    }

    CMagicDoorMonGroup& stMonGroup = GetMagicDoorMonGroup();

    switch (stReq.sub_type())
    {
    case ID_GM_PLAYER_SUB_GET_MAGIC_DOOR:
        {
            szNameStr.Cat("家族ID:%u 家族名:%s 贡献度:%d 排名充能次数:%d " \
                "23时周期充能次数:%d 门开启后充能次数:%d \n场景地图:%u " \
                "普通怪物:%u 特殊怪物:%u 世界等级:%d 当天限制:%d",
                stClanEntry._uiClanId,stClanEntry._szName.Get(),
                stPlayerSnsDetail._stCommInfo._iContribution,
                GetTotalPayTimes(stPlayerDetail, stClanEntry),
                GetPayContriTimes(stPlayerDetail, true),
                GetPayContriTimes(stPlayerDetail, false),
                stMonGroup.GetMapID(),stMonGroup.GetNormalID(),
                stMonGroup.GetSpecialID(),stClanEntry._stMagicDoor._iWorldLevel,
                GetCheckJoinDay());

            szNameStr.Cat("\n魔界门充能等级:%d 开启等级:%d 状态:%d 经验:%d " \
                "开启时间:%d 开启次数:%d",stClanEntry._stMagicDoor._chNowLevel,
                stClanEntry._stMagicDoor._chOpenLevel,
                stClanEntry._stMagicDoor._chStatus,
                stClanEntry._stMagicDoor._iExp,
                stClanEntry._stMagicDoor._iOpenTime,
                stClanEntry._stMagicDoor._stDailyCounts.Get(
                    CMainCtrl::m_pstMain->m_iNow));

            szNameStr.Cat("\n充能排行榜总数:%d",
                stClanEntry._stMagicDoor._astContriList.Size());
            for (int i = 0; i < stClanEntry._stMagicDoor._astContriList.Size();
                    ++i)
            {
                CMagicDoorContriUnit& stRankUnit =
                    stClanEntry._stMagicDoor._astContriList[i];
                szNameStr.Cat(" GID:%u %s 次数:%d",stRankUnit.GetGID(),
                    stRankUnit.GetRoleName(),stRankUnit.GetCount());
            }

            szNameStr.Cat("\n怪物总数:%d",
                stClanEntry._stMagicDoor._astMonsterList.Size());
            for (int i = 0; i < stClanEntry._stMagicDoor._astMonsterList.Size();
                    ++i)
            {
                if (0 == i || i % 3 == 0)
                {
                    szNameStr.Cat("\n");
                }
                CMagicDoorMonUnit& stMonUnit =
                    stClanEntry._stMagicDoor._astMonsterList[i];
                szNameStr.Cat("[No:%d Max:%d Now:%d] ",i,
                    stMonUnit.GetMaxHP(),stMonUnit.GetNowHP());
            }

            stAns.set_name(szNameStr.Get());
        }
        break;
    default:
        return ERROR_MAIN_SUB_CMD;
    }

    return 0;
}

